Amazon SQS
https://gyazo.com/45ea120fe1875061a57469f49a1881a5
Amazon Simple Queue Service_
マネージドなMessage Queueサービス
ProducerとConsumerを疎結合にして、スパイク吸収・再試行・バックプレッシャーを実現する
code:_
生産者 (Producer) ──→ SQS Queue ──→ 消費者 (Consumer)
例: S3 通知 例: app
2種類のqueueがある
table:_
Standard Queue (sqs) FIFO Queue (sqs)
順序保証 ベストエフォート 厳密にFIFO
重複 ごく稀に発生する可能性あり 重複排除あり
スループット 無制限 制限あり
名前 任意 .fifo 接尾辞が必須
最大14日間メッセージをキューに保持できる
#WIP
https://speakerdeck.com/pikosan0000/sqs-lambda-devday2022
AWS Lambdaと組み合わせる
/mrsekut-book-486354314X/036
主な操作
table:_
操作 何をする
SendMessage メッセージをキューに入れる
ReceiveMessage キューからメッセージを取り出す(最大10件)
DeleteMessage 処理完了したメッセージをキューから消す
ChangeMessageVisibility 処理時間が延びそうなときにロック延長
gpt-5.icon
基本パラメータ
Visibility Timeout (sqs)
Long Polling (sqs)
Message Retention
保持期間(最大 14 日)。
最大ペイロード 256KB(大きいデータは S3 へ、S3 のキーをメッセージに載せるのが定石)。
エラーハンドリング
DLQ(デッドレターキュー)
一定回数失敗したメッセージを隔離し、後で調査・再処理。
セキュリティ / 運用
サーバサイド暗号化(SSE)対応、IAM / キューポリシーでアクセス制御、CloudWatch で可視化。
送信(Producer)
code:ts
// npm i @aws-sdk/client-sqs
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
const client = new SQSClient({ region: "ap-northeast-1" });
const queueUrl = process.env.ORDERS_QUEUE_URL!; // 例: Terraform 出力から渡す
async function sendOrder(order: { id: string; items: string[] }) {
const cmd = new SendMessageCommand({
QueueUrl: queueUrl,
MessageBody: JSON.stringify(order),
// FIFO の場合のみ(Standardなら不要)
// MessageGroupId: "order-events",
// MessageDeduplicationId: order.id, // content_based_deduplication=false の時
});
await client.send(cmd);
}
受信 & 処理(Consumer)
code:ts(ts)
import {
SQSClient,
ReceiveMessageCommand,
DeleteMessageBatchCommand,
} from "@aws-sdk/client-sqs";
const client = new SQSClient({ region: "ap-northeast-1" });
const queueUrl = process.env.ORDERS_QUEUE_URL!;
async function pollAndProcess() {
const resp = await client.send(new ReceiveMessageCommand({
QueueUrl: queueUrl,
MaxNumberOfMessages: 10,
WaitTimeSeconds: 20, // Long Polling
VisibilityTimeout: 60, // 処理に必要な秒数
}));
if (!resp.Messages?.length) return;
// ここで順次処理(例外時は throw せず可観測化+再試行が原則)
for (const m of resp.Messages) {
const payload = JSON.parse(m.Body!);
// TODO: ビジネスロジック
}
// 正常に処理できたら削除(取りこぼすと再配信される)
await client.send(new DeleteMessageBatchCommand({
QueueUrl: queueUrl,
Entries: resp.Messages.map((m) => ({
Id: m.MessageId!,
ReceiptHandle: m.ReceiptHandle!,
})),
}));
}